《Qt Quick核心编程 》 学习 您所在的位置:网站首页 qt quick核心编程 下载 《Qt Quick核心编程 》 学习

《Qt Quick核心编程 》 学习

2022-06-12 08:46| 来源: 网络整理| 查看: 265

知识点: 自定义按钮: import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Button { id:btn x: 0 y: 62 text: "Quit2" style:ButtonStyle { background: Rectangle { implicitWidth: 100 implicitHeight: 25 border.width: btn.pressed ? 2 : 1 } } } } main.qml 多个窗口: import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 1.4 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Button { // 会默认放到 data 列表中 id:btn text: "Quit" } Window { id: root2 visible: true title: qsTr("Hello World") width: 300 height: 100 flags: Qt.Popup Text{ text: "Hello Qt Quick" } } } main.qml 颜色 LinearGradient : import QtQuick 2.12 import QtQuick.Window 2.12 import QtGraphicalEffects 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ width: 500 height: 500 border.color: Qt.lighter("purple") border.width: 2 radius: 15 LinearGradient { anchors.fill: parent start: Qt.point(0, 0) end: Qt.point(500, 500) gradient: Gradient { GradientStop { position: 0.000 color: Qt.rgba(1, 0, 0, 1) } GradientStop { position: 0.167 color: Qt.rgba(1, 1, 0, 1) } GradientStop { position: 0.333 color: Qt.rgba(0, 1, 0, 1) } GradientStop { position: 0.500 color: Qt.rgba(0, 1, 1, 1) } GradientStop { position: 0.667 color: Qt.rgba(0, 0, 1, 1) } GradientStop { position: 0.833 color: Qt.rgba(1, 0, 1, 1) } GradientStop { position: 1.000 color: Qt.rgba(1, 0, 0, 1) } } source: Image { source:"images/ufo.png" } } Component.onCompleted: { console.log(color.r,color.g,color.b,color.a); } } } main.qml

 

Text 控件 多余文字显示 三个点: import QtQuick 2.12 import QtQuick.Window 2.12 import QtGraphicalEffects 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 color: "cyan" Rectangle{ id:rect1 color: "purple" width: 150 height: 100 Text { id: txt1 anchors.fill:parent text: qsTr("Hello Red Text,Hello Red Text,Hello Red Text,Hello Red Tex") color:"red" clip: true wrapMode: Text.WrapAnywhere elide: Text.ElideRight } } } View Code

Image 相关:

显示GIF 图片:

Image不能显示GIF,因为Image只能显示静态图片,可以使用 AnimatedImage 显示动态图片 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 color: "cyan" Image { id: img1 width: 100 height: 100 source: "images/1.gif" // 不能显示GIF,因为Image只能显示静态图片 } // 可以使用 AnimatedImage 显示动态图片 AnimatedImage { id:aniImg1 x:100 y:100 width: 100 height: 100 source: "images/1.gif" } } View Code

 

异步加载网络图片:

使用了 BusyIndicator 组件

import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 color: "cyan" Rectangle{ width: 500 height: 500 border.color: "red" border.width: 2 BusyIndicator{ id:loading running: true anchors.centerIn: parent z:2 // z-index } Text { id: desc visible: false anchors.centerIn: parent z:3 // z-index } Image { id: img1 cache: false // 在加载大型图片一般不要进行缓存 anchors.fill: parent source: "http://pic1.juimg.com/161122/330846-16112222051832-lp.jpg" fillMode: Image.PreserveAspectFit asynchronous: true // 开启异步加载 图片 网络资源自动就是异步,本地资源默认都是同步 onStatusChanged: { if(img1.status === Image.Loading){ loading.running = true; desc.visible = false; // console.log("loading"); }else if(img1.status === Image.Ready){ loading.running = false; // console.log("ready"); }else if(img1.status === Image.Error){ loading.running = true; desc.visible = true; desc.text = "load img error"; // console.log("error"); } } // focus: true // Keys.onPressed: { // if(event.key === Qt.Key_A){ // console.log(img1.status,"|||| ",Image.Error); // } // } } } } View Code

效果:

 

图片查看器(一次打开单张图片):

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 minimumWidth: 480 minimumHeight: 360 BusyIndicator{ id:loading running: false anchors.centerIn: parent z:2 } Text { id: stateTxt visible: false anchors.centerIn: parent z:3 } Image { id: imageViewer asynchronous: true // 异步加载 cache: false // 关闭缓存 anchors.fill: parent fillMode: Image.PreserveAspectFit onStatusChanged: { if(imageViewer.status === Image.Loading){ loading.running = true; stateTxt.visible = false; }else if(imageViewer.status === Image.Ready){ loading.running = false; }else if(imageViewer.status === Image.Error){ loading.running = true; stateTxt.visible = true; stateTxt.text = "load image error"; } } } Button{ id:openFile text: "Open" anchors.left: parent.left anchors.leftMargin: 8 anchors.bottom: parent.bottom anchors.bottomMargin: 8 onClicked:fileDialog.open() } FileDialog{ id:fileDialog title: "Please choose a file" nameFilters: ["Image Files (*.jpg *.png *.gif)"] onAccepted: { imageViewer.source = fileDialog.fileUrl; var imageFile =new String(fileDialog.fileUrl); imagePath.text = imageFile.slice(8); } } Text { id: imagePath anchors.left: openFile.right anchors.leftMargin: 8 anchors.verticalCenter: openFile.verticalCenter font.pixelSize: 18 } } main.qml

 

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 minimumWidth: 480 minimumHeight: 360 BusyIndicator{ id:loading running: false anchors.centerIn: parent z:2 } Text { id: stateTxt visible: false anchors.centerIn: parent z:3 } Image { id: imageViewer asynchronous: true // 异步加载 cache: false // 关闭缓存 anchors.fill: parent fillMode: Image.PreserveAspectFit onStatusChanged: { if(imageViewer.status === Image.Loading){ loading.running = true; stateTxt.visible = false; }else if(imageViewer.status === Image.Ready){ loading.running = false; }else if(imageViewer.status === Image.Error){ loading.running = true; stateTxt.visible = true; stateTxt.text = "load image error"; } } } Button{ id:openFile text: "Open" anchors.left: parent.left anchors.leftMargin: 8 anchors.bottom: parent.bottom anchors.bottomMargin: 8 onClicked:fileDialog.open() } FileDialog{ id:fileDialog title: "Please choose a file" nameFilters: ["Image Files (*.jpg *.png *.gif)","Bitmap Files (*.bmp)","* (*.*)"] selectedNameFilter:"Image Files (*.jpg *.png *.gif)" // 默认过滤器 selectMultiple: true // 选择多个文件 onAccepted: { imageViewer.source = fileDialog.fileUrls[0]; var imageFile =new String(fileDialog.fileUrl[0]); imagePath.text = imageFile.slice(8); } } Text { id: imagePath anchors.left: openFile.right anchors.leftMargin: 8 anchors.verticalCenter: openFile.verticalCenter font.pixelSize: 18 } } 一次可以选择多个文件

 

Loader:

Loader 用来动态加载QML Component 组件,

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Loader{ id:redLoader anchors.left: parent.left anchors.leftMargin: 4 anchors.bottom: parent.bottom anchors.bottomMargin: 4 sourceComponent: colorComponent onLoaded: { item.color = "red"; // 这里的item 指的是 所加载的顶层对象即 rect } } Component{ id:colorComponent // 注Component 中只能有一个id 属性 和 一个顶层对象!!! Rectangle{ id:rect width: 50 height: 50 signal zcb(color clr) MouseArea{ anchors.fill: parent onPressed: rect.zcb(rect.color) } onZcb:{ rect.color = "yellow"; } } } } View Code

如果Loader加载的Item 想要处理按键事件,必须要把Loader 中的 focus 设置为true

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Loader{ id:redLoader anchors.left: parent.left anchors.leftMargin: 4 anchors.bottom: parent.bottom anchors.bottomMargin: 4 sourceComponent: colorComponent onLoaded: { item.color = "red"; } // 如果Loader加载的Item 想要处理按键事件,必须要把Loader focus 设置为true,这样它所加载的组件才可以接收到focus focus: true // 开启按键事件 } Component{ id:colorComponent Rectangle{ id:rect width: 50 height: 50 signal zcb(color clr) MouseArea{ anchors.fill: parent onPressed: rect.zcb(rect.color) } onZcb:{ rect.color = "yellow"; } focus: true Keys.onPressed: { console.log(event.key); event.accepted = true; } } } } View Code

 

从文件中加载组件:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Loader{ id:redLoader anchors.left: parent.left anchors.leftMargin: 4 anchors.bottom: parent.bottom anchors.bottomMargin: 4 // sourceComponent: colorComponent source: "MyTest.qml" onLoaded: { console.log(item); //此时 item 仍然是顶层对象 item.color = "red"; } // 如果Loader加载的Item 想要处理按键事件,必须要把Loader focus 设置为true,这样它所加载的组件才可以接收到focus focus: true // 开启按键事件 } } main.qml import QtQuick 2.10 Rectangle{ id:colorComponent width: 50 height: 50 signal zcb(color clr) MouseArea{ anchors.fill: parent onPressed: colorComponent.zcb(colorComponent.color) } onZcb:{ colorComponent.color = "yellow"; } focus:true Keys.onPressed: { console.log(event.key); event.accepted = true; } } MyTest.qml

 

动态创建和销毁控件:

利用Loader,可以通过设置source为 空串,设置sourceComponent 为undefined 可以销毁控件 ~

 

在js 中动态创建组件对象:

有两种方式:

1,使用Qt.createComponent()  动态创建一个组件对象,然后使用Component 的createObject() 创建它的实例对象。 

2,使用Qt.createQmlObject()  从一个QML字符串直接创建一个实例对象

注:

如果已经有一个QML文件中定义了一个组件,你想创建它的实例对象,这时使用1较好。

如果QML对象本身是在运行时产生的,那么Qt.createQmlObject() 可能是比较好的选择。 

 

第一种,

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect anchors.fill: parent focus: true Keys.onPressed: { if(event.key === Qt.Key_A){ // 创建组件对象 var newCom = Qt.createComponent("MyTest.qml"); newCom.createObject(rect,{"color":"cyan"});// 第一个参数为父级,后面是新创建组件的属性 } } } } main.qml import QtQuick 2.10 Rectangle{ id:colorComponent width: 50 height: 50 signal zcb(color clr) MouseArea{ anchors.fill: parent onPressed: colorComponent.zcb(colorComponent.color) } onZcb:{ colorComponent.color = "yellow"; } focus:true Keys.onPressed: { console.log(event.key); event.accepted = true; } } MyTest.qml

 

第二种,

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect anchors.fill: parent focus: true Keys.onPressed: { if(event.key === Qt.Key_A){ // 创建组件对象 var newCom = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20;}', rect, "newCom01"); // 第三个参数 是给对象关联一个文件路径,主要用于报告错误 } } } } main.qml

 

销毁动态创建的对象:

这里说的销毁不是仅仅把对象的visible 设为false或者是opacity 设置为0 。

需要调用 destroy() 函数,

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Controls 2.10 import QtQuick.Dialogs 1.3 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect anchors.fill: parent property var mycom: null focus: true Keys.onPressed: { if(event.key === Qt.Key_A){ // 创建组件对象 rect.mycom = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20;}', rect, "newCom01"); // 第三个参数 是给对象关联一个文件路径,主要用于报告错误 } if(event.key === Qt.Key_B){ console.log(rect.mycom); rect.mycom.destroy(0); // 0s 后销毁 } } } } main.qml

点击a 创建,点击b 销毁~

 

Qt Quick 元素布局:

三大类:

1,前面说过的 锚布局(Anchor),它是利用Item 的anchors 属性实现,非常方便!!!

2,定位器(Position),它包含了Row(行定位器),Column(列定位器),Grid(表格定位器),Flow(流定位器)

3,布局管理器(Layout),它包含  行布局(RowLayout),列布局(ColumnLayout),表格布局(GridLayout)

定位器Position

布局管理器Layout 

Qml 的布局管理器和 Qt widgets 相似,它与定位器的不同之处在于:布局管理器会自动调整子Item 的尺寸来适应界面大小的变化。

要使用布局管理器,需要引入Layouts 模块。

GridLayout:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rootItem width: 360 height: 240 color:"#eee" GridLayout{ width: 200 anchors.left: parent.left anchors.leftMargin: 4 anchors.top: parent.top anchors.topMargin: 4 rows:2 columns: 2 rowSpacing: 4 columnSpacing: 4 Rectangle{ id:rect1 width:100 height: 100 color: "purple" Layout.columnSpan: 2 Layout.rowSpan: 2 Layout.fillWidth: true } Rectangle{ id:rect2 width:100 height: 100 color: "cyan" } Rectangle{ id:rect3 width:100 height: 100 color: "yellow" } } } } main.qml

RowLayout

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rootItem width: 400 height: 240 color:"#eee" RowLayout{ width: 400 anchors.left: parent.left anchors.leftMargin: 4 anchors.top: parent.top anchors.topMargin: 4 Rectangle{ id:rect1 width:100 height: 100 color: "purple" } Rectangle{ id:rect2 width:100 height: 100 color: "cyan" } Rectangle{ id:rect3 width:100 height: 100 color: "yellow" Layout.fillWidth: true } } } } main.qml

ColumnLayout:

类似... 

 

QML  常用控件:

1,行编辑:

TextInput ,TextField

2,文本块:

TextEdit,TextArea

3,互斥分组:

ExclusiveGroup 

4,RadioButton:

单选按钮

5,CheckBox:

多选框

6,GroupBox:

分组框

7,ComboBox:

下拉框

8,ProgressBar:

进度条

9,TabView:

点击标签会进入对应界面,选项卡控件

10,Slider:

滑块控件

11,Flickable:

Flickable提供一个较小的视窗来显示一个较大的内容给用户,并且用户可以对改内容进行拖拽和轻拂

12,Screen:

它是显示Item 的那个屏幕,它提供了一些只读属性来描述屏幕参数。

 

Canvas 画布:

Canvas 是Item 的派生类,

1,画布:

Canvas{ width: 300 height: 200 } View Code

这即是一块画布,

 

2,画师:

画师是Context2D ,QT帮助文档直接搜索Context2D ,

Canvas{ width: 300 height: 200 onPaint: { var ctx = getContext("2d"); // 在QML 中,一块画布只有一个画师 } } View Code

 

3,画笔:关于画笔的属性设置,在Contex2D对象 上都有,有笔的粗细(lineWidth),笔的颜色(strokeStyle)之类的

 

4,画刷:

画刷是用来填充画笔勾勒出的区域的,属性是fillStyle,

 

坐标系:

在2D世界,原点位于屏幕左上角(0,0), 向右是x 轴,向下是y轴。

图元:

基本的图元有线,弧,矩形,曲线,文本,图片,

小试牛刀:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 onPaint: { var ctx = getContext("2d"); // 在QML 中,一块画布只有一个画师 ctx.lineWidth = 2; ctx.strokeStyle = "red"; // 画笔颜色 ctx.fillStyle = "blue"; // 画刷 颜色 ctx.beginPath(); ctx.rect(60,50,120,80); ctx.fill(); ctx.stroke(); // 使用stroke() 结束路径的绘制 var gradient = ctx.createRadialGradient(200,140,40,280,220,20); gradient.addColorStop(0.0,Qt.rgba(1,0,0,1.0)); gradient.addColorStop(1.0,Qt.rgba(0,0,1,1.0)); ctx.fillStyle = gradient; ctx.beginPath(); ctx.rect(200,140,80,80); ctx.fill(); ctx.stroke(); } } } main.qml import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 onPaint: { var ctx = getContext("2d"); // 在QML 中,一块画布只有一个画师 ctx.lineWidth = 2; ctx.strokeStyle = "red"; // 画笔颜色 ctx.fillStyle = "blue"; // 画刷 颜色 ctx.beginPath(); ctx.moveTo(100,80); // 移动到 100,80 ctx.lineTo(100,200); // 从当前位置到(x,y)点绘制一条直线 ctx.lineTo(300,200); ctx.closePath(); // 结束当前的路径,从路径终点到起点绘制一条直线来封闭路径 ctx.fill(); ctx.stroke(); // 使用stroke() 结束路径的绘制 } } } main.qml import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 onPaint: { var ctx = getContext("2d"); // 在QML 中,一块画布只有一个画师 ctx.lineWidth = 2; ctx.strokeStyle = "red"; // 画笔颜色 ctx.fillStyle = "blue"; // 画刷 颜色 ctx.font = "42px sans-serif"; ctx.beginPath(); ctx.moveTo(4,4); ctx.bezierCurveTo(0,height - 1,width -1 ,height/2,width/4,height/4); ctx.lineTo(width/2,height/4); ctx.arc(width*5/8,height/4,width/8,Math.PI,0,false); ctx.ellipse(width*11/16,height/4,width/8,height/4); ctx.lineTo(width/2,height*7/8); ctx.text("Hello World",width/4,height*7/8); ctx.fill(); ctx.stroke(); // 使用stroke() 结束路径的绘制 } } } View Code

 

与文本相关:

有三个方法:fillText()  ,strokeText(),text()

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 onPaint: { var ctx = getContext("2d"); // 在QML 中,一块画布只有一个画师 ctx.lineWidth = 2; ctx.strokeStyle = "red"; // 画笔颜色 ctx.font = "42px sans-serif"; ctx.fillStyle = "green"; // 画刷颜色 //1 ctx.beginPath(); ctx.text("Hello World -fill",50,50); ctx.fill(); //2 ctx.fillText("Hello World -fillText",50,150); //3 ctx.beginPath(); ctx.text("Hello World -stroke",50,200); ctx.stroke(); //4 ctx.strokeText("Hello World -strokeText",50,250); //5 ctx.beginPath(); ctx.text("Hello World -fill -stroke",50,300); ctx.fill(); ctx.stroke(); } } } View Code

绘制图片:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 property var imgSrc:"images/rocket.png" onPaint: { var ctx = getContext("2d"); //1 ctx.drawImage(imgSrc,100,100); } Component.onCompleted: loadImage(imgSrc); // loadImage 会异步加载图片,当图片加载完成时会发射imageLoaded 信号 onImageLoaded: { requestPaint(); // 重新绘制 Canvas 画布 } } } View Code

变换:

平移(translate),旋转(rotate),缩放(scale),错切(shear),

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 property var imgSrc:"images/rocket.png" onPaint: { var ctx = getContext("2d"); ctx.lineWidth = 2; ctx.strokeStyle = "blue"; ctx.fillStyle = "purple"; ctx.save(); ctx.beginPath(); ctx.translate(width/2,height/2); ctx.arc(0,0,30,0,Math.PI*2); ctx.arc(0,0,50,0,Math.PI*2); ctx.arc(0,0,70,0,Math.PI*2); ctx.arc(0,0,90,0,Math.PI*2); ctx.stroke(); ctx.restore(); // 恢复到save() 之前的状态 ctx.save(); ctx.translate(width/2,30); ctx.font = "42px sans-serif"; ctx.textAlign="center"; ctx.fillText("concentric circles",0,0); ctx.restore(); } } } View Code

Note :restore()  和 save()结合使用,

裁剪:

Context2D 的clip()  方法,让我们能够根据当前路径包围的区域来裁剪。

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ width: 800 height: 600 property var imgSrc:"images/1.jpg" onPaint: { var ctx = getContext("2d"); ctx.lineWidth = 2; ctx.strokeStyle = "blue"; ctx.fillStyle = Qt.rgba(0.3,0.5,0.7,0.3); ctx.save(); ctx.beginPath(); ctx.arc(180,150,80,0,Math.PI*2,true); ctx.closePath(); ctx.clip(); // 裁剪 ctx.drawImage(imgSrc,0,0); ctx.stroke(); ctx.fill(); ctx.rotate(Math.PI/5); ctx.font = "italic bold 32px serif"; ctx.fillStyle = "red"; // 字体填充颜色 ctx.fillText("Hello World,Wosdfjklf ",100,70); ctx.restore(); } Component.onCompleted: loadImage(imgSrc); onImageLoaded: requestPaint(); } } View Code

图像合成:

globalCompositeOperation 

 

QML 动画: 基本动画对象:

PropertyAnimation: 通过改变各种类型的property 来产生动画

NumberAnimation:  PropertyAnimation 的子类,专门改变数字类型的property来产生动画,效率比PropertyAnimation 好,

ColorAnimaiton :  PropertyAnimation 的子类,专门改变color 类型的property 来产生动画,效率比PropertyAnimation 好,

RotationAnimaiton :  PropertyAnimation 的子类,专门改变rotation 值来产生动画,效率比PropertyAnimation 好,另外还提供旋转方向等附加属性,

Vector3dAnimation:  PropertyAnimation 的子类,当一个Vector3d值 发生变化时使用。

PathAnimation: 让对象沿一个给定的方向移动

SmoothedAnimation: 允许一个property 跟踪一个值,产生平滑动画

SpringAnimation, 允许一个property 跟踪一个值,动画效果类似于弹簧运动,

分组动画对象:

SequentialAnimation: 顺序执行一系列动画

ParallAnimation :  并行执行一系列动画

 

动画搭档:

State,它是Item的状态,不同状态对应不同的界面效果和业务逻辑。

Transition, 过渡,它用来衔接不同状态,使状态变化过程平滑。

 

协同动画元素:

Behavior : 它为Item 的property 变化绑定一个默认的动画对象。

ParentAnimation, 当改变一个Item的parent的时候使用,使得从旧parent到新parent的过程更平滑,通常与State,Transition,ParentChange联合使用。

AnchorAnimation: 当改变一个Item 的 anchor的时候使用,通常与State,Transition,AnchorChange联合使用。

PauseAnimation:如果在动画过程插入它,可以将动画过程暂停一段时间。

PropertyAction: 动画执行过程立即改变某个属性。

ScriptAction:动画执行过程运行一段JS脚本。

 

测试代码:

PropertyAnimation定义的三种方式:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 50 anchors.centerIn: parent color: "blue" MouseArea{ anchors.fill: parent onClicked: animation.running = true; } } Rectangle{ id:rect2 width: 50 height: 50 color: "red" } PropertyAnimation{ id:animation targets: [rect,rect2] properties: "width,height" to:150 duration: 1000; } } View Code import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 50 anchors.centerIn: parent color: "blue" MouseArea{ anchors.fill: parent onClicked: PropertyAnimation{ // 在信号处理器中直接使用动画 id:animation target: rect properties: "width,height" to:150 duration: 1000; } } } } 在信号处理器中直接使用动画 import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 50 anchors.centerIn: parent color: "blue" MouseArea{ id:mouseArea anchors.fill: parent } PropertyAnimation on width{ // Animation on 这种语法格式 可以将一个动画和一个属性关联起来 to:150 duration: 1000 running: { return mouseArea.pressed } } } } Animation on 语法格式

Animation 的started() 和 stopped() 信号:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 150 anchors.centerIn: parent color: "blue" property var animation; PropertyAnimation{ id:toSquare target: rect property: "width" to:150 duration: 1000 onStarted: { rect.animation = toSquare; rect.color = "red"; } onStopped: { rect.color = "blue"; } } PropertyAnimation{ id:toRect target: rect property: "width" to:50 duration: 1000 onStarted: { rect.animation = toRect; rect.color = "red"; } onStopped: { rect.color = "blue"; } } MouseArea{ id:mouseArea anchors.fill: parent onClicked: { if(rect.animation == toRect || rect.animation == undefined){ toSquare.start(); }else{ toRect.start(); } } } } } View Code

 

NumberAnimation:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 150 anchors.centerIn: parent color: "blue" NumberAnimation { id:numAni target: rect property: "width" to:150 duration: 200 easing.type: Easing.InOutQuad } MouseArea{ id:mouseArea anchors.fill: parent onClicked: { numAni.running = true; } } } } View Code

ColorAnimation:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 150 anchors.centerIn: parent color: "blue" MouseArea{ id:mouseArea anchors.fill: parent onClicked: ColorAnimation { target: rect property: "color" to: "green" duration: 200 } } } } View Code

RotationAnimation:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 50 height: 150 anchors.centerIn: parent color: "blue" // transformOrigin: Item.TopRight Text { id: txt anchors.fill: parent text: qsTr("text") } MouseArea{ id:mouseArea anchors.fill: parent onClicked: RotationAnimation{ target: rect to:90 duration: 1000 direction: RotationAnimation.Clockwise // 顺时针 } } } } View Code

PathAnimation:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Canvas{ // 画一个半圆 width: 400 height: 240 onPaint: { var ctx = getContext("2d"); ctx.lineWidth = 4; ctx.strokeStyle = "red"; ctx.beginPath(); ctx.arc(200,0,160,Math.PI*2,0,false); ctx.stroke(); } } Rectangle{ id:rect width: 40 height: 40 color: "blue" x:20 y:0 MouseArea{ id:mouseArea anchors.fill:parent onClicked: pathAnim.start(); } PathAnimation{ id:pathAnim target: rect duration: 6000 anchorPoint: "20,20"// rect 的center orientation: PathAnimation.BottomFirst orientationEntryDuration: 200 // 调整初始姿态的时间 endRotation: 0 // 最后的角度 :0 orientationExitDuration: 200 // 调整终止时姿态的时间 easing.type: Easing.InOutCubic path: Path{ startX: 40 startY: 0 PathArc{ x:360 // 终点(360,0) y:0 useLargeArc: true; // 采用 优弧(较大)模式 radiusX: 160 // 椭圆的两个半轴 radiusY: 160 direction: PathArc.Counterclockwise // 逆时针 } } } } } View Code

SmoothedAnimation:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 40 height: 40 color: "red" x:20 y:20 SmoothedAnimation{ // SmoothedAnimation默认采用 easing.type 为InOutQuad id:smoothAni1 target: rect property: "x" duration: 1000 velocity: -1 //速率 默认速率是200units/秒, -1 为禁用速率 // 如果duration和 velocity同时设置,那么会使用速率计算出一个时间, 它和duration的较短者会被采用。 } SmoothedAnimation{ id:smoothAni2 target: rect property: "y" velocity: 100 } } MouseArea{ anchors.fill: parent onClicked: { smoothAni1.from = rect.x; smoothAni1.to = mouse.x + 4; smoothAni1.start(); smoothAni2.from = rect.y; smoothAni2.to = mouse.y + 4; smoothAni2.start(); } } } View Code

 

SpringAnimation:

可以用来模拟弹簧的震荡行为,

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 40 height: 40 color: "red" x:20 y:20 } SpringAnimation{ id:springAni1 target: rect property: "x" spring: 3 // 加速度 0-5 有意义 默认为0 damping: 0.06 //衰减系数0-1.0 有意义, 值越大会越快平复 epsilon: 0.25 //允许设定一个最接近0 的阈值代表0 ,如果是基于像素动画,建议0.25 ,如果是基于scale动画,建议0.005 。 默认为0.01 ,调整epsilon 可能会有一定的性能提升 } SpringAnimation{ id:springAni2 target: rect property: "y" spring: 3 damping: 0.06 epsilon: 0.25 } MouseArea{ anchors.fill: parent onClicked: { springAni1.from = rect.x; springAni1.to = mouse.x - 20; springAni1.start(); springAni2.from = rect.y; springAni2.to = mouse.y - 20; springAni2.start(); } } } View Code

 

组合动画:

State:

在QML中,状态是定义在State类型中的一系列属性配置。不同的配置可能有不同的作用:

1,显示一些UI组件,隐藏另一些

2,想用户呈现不同的操作和功能

3,启动,暂停,停止动画

4,在某种新的状态下执行某些脚本

5,改变某个特定Item的property的值

6,显示一个不同的view或screen 

等等...

代码:

import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 360 height: 240 color: "#eee" Text { id: centerTxt text: qsTr("Just a text!") anchors.centerIn: parent font.pixelSize: 24 MouseArea{ id:mouseArea anchors.fill: parent onPressed: { centerTxt.state = "blueText"; } onReleased: { centerTxt.state = "redText"; } } state:"redText" states: [ State { name: "redText" changes: [ PropertyChanges { target: centerTxt color:"red" } ] }, State { name: "blueText" PropertyChanges { target: centerTxt color:"blue" } } ] } } } 使用State 变换文本 import QtQuick 2.10 import QtQuick.Window 2.10 import QtQuick.Layouts 1.12 Window { id: root visible: true title: qsTr("Hello World") width: 800 height: 600 Rectangle{ id:rect width: 360 height: 240 color: "#eee" Text { id: centerTxt text: qsTr("Just a text!") anchors.centerIn: parent font.pixelSize: 24 MouseArea{ id:mouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton } state:"redText" states: [ State { name: "redText" when:mouseArea.pressedButtons === Qt.RightButton changes: [ PropertyChanges { target: centerTxt color:"red" }, PropertyChanges { target: centerTxt font.bold:true font.italic: true } ] }, State { name: "blueText" when: mouseArea.pressed PropertyChanges { target: centerTxt color:"blue" font.pixelSize: 48; } } ] } } } 点击左右鼠标键,产生不同效果

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C++ 与 QML 混合编程: 在QML中使用c++ 类和对象:

要想将一个类或对象导出到QML,前提条件是:

1,从QObject 或 QObject 的派生类继承  

2,使用Q_OBJECT 宏  

 

省略...

 

 

 

 

 

 

 

 

 

 

在QML中使用c++ 类和对象:

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有